home *** CD-ROM | disk | FTP | other *** search
- ; display backgound stars, 1024 stars. routine is designed so only stars
- ; which will be on the screen are calculated. this is first done with
- ; x angle indexing, then with y angle clipping, then with z distance clipping.
- ; this way, stars which most likely wont be visable are not rotated with those
- ; time-consuming IMUL's. a mode has also been added to make non-perfect 3d
- ; stars. this mode requires that the constants xstar and ystar be adjusted
- ; by the user the make the stars "look" the same as perfectly calculated stars
- ; however, when these values are adjusted correctly, this routine is about 40%
- ; faster. this can be done because the stars are at a constant distance from
- ; the camera.
-
- .386p
- jumps
-
- code32 segment para public use32
- assume cs:code32, ds:code32
-
- include pmode.inc ; protected mode externals
- include xmode.inc ; include externals for xmode routines
- include macros.inc
- include equ.inc ; every .asm should have access to this stuff
- include 3d.inc
-
- include stardata.inc
-
- public show_stars
-
- ; angle tolerence (lower untill stars get clipped)
- ;largest equ 93 ; this is good without using z rotations in 320x400
- largest equ 150 ; this is good with using z rotations in 320x400
-
- ; this is only used when perfect_stars = yes
- zdistance equ 14500 ; z clipping parameter, 16384 = all stars clipped
-
- xstar equ ratiox*4/128 ; these are divided by 4 to give decimals.
- ystar equ ratioy*4/128 ; used when perfect_stars=no
-
- starcolour equ 12 ; colour for star, 1st of four (indexed from palette)
-
- number_of_stars equ 1024 ; must be 2^some_number
- cut equ 5
-
-
- ;use_half_stars equ no ; both already defined in equ.inc
- ;perfect_stars equ no ; fast star calculation if no
-
- smatrix dd 6 dup (0) ; star matrix, ematrix*xscale*yscale
- angle_count dw 0
- starhalfpoint dw 512 ;400,600? ; lower cutoff if use_half_stars = yes
-
- we_is_out_of_here:
- ret
-
- show_stars:
- movzx esi,eyeax ; get camera x angle
- add si,16384 ; 1/4 quadrant
- shr si,5 ; 32768/2^5 = 1024
-
- mov ebp,esi
- add bp,largest ; sweep to bottom
- sub si,largest ; start from top
-
- cmp bp,number_of_stars-cut
- jle s okmax
- mov bp,number_of_stars-cut
- okmax:
- cmp si,cut
- jge s ok_min
- mov si,cut ; looking almost directly up
- ok_min:
- movzx esi,xn1[esi]
- movzx ebp,xn1[ebp]
-
- mov ax,bp
- sub ax,si
- shl ax,2
- mov angle_count,ax
-
- shl si,2
-
- ;mov angle_count,number_of_stars
- ;mov esi,0 ; uncomment this!! (along with stuff below)
-
- if use_half_stars eq yes
- cmp si,starhalfpoint
- jae s we_is_out_of_here
- endif
-
- call set_star_matrix ; pre-cal star matrix
-
- more_stars:
- movsx ax,sya[esi] ; star_y_angle
- neg ax
- shl ax,8
- sub ax,eyeay
-
- shr ax,8
- movsx ax,al
-
- mov bl,tol[esi] ; bx = tol *256
- xor bh,bh
- mov cx,bx
-
- shr cx,1
- add ax,cx
-
- cmp ax,0 ; check left or right of screen
- jl skipit
-
- cmp ax,bx
- jg skipit ; try removing these skipit jumps!!!
-
- push esi
-
- movsx ebx,sxl[esi] ; star_x_location
- movsx ecx,syl[esi]
- movsx ebp,szl[esi]
-
- if perfect_stars eq yes
- shl ebx,7 ; * for some accuracy
- shl ecx,7
- shl ebp,7
-
- call srotatez ; star is eligable, calculate actual screen loc
-
- ;add esi,50000 ; try this too! (this is the best part)
-
- cmp esi,zdistance ; clip if too close (not on apex of sphere)
- jl abort_s
- endif
-
- call srotatex ; check tolerence in parts (saves imul's)
-
- if perfect_stars eq yes
- mov eax,edi ; some code from make3d routine (math.inc)
- cdq
- idiv esi ; if fast mode selected, avoid idiv's
- mov edi,eax
- endif
-
- cmp di,xmins ; draw single point/bullet
- jl s abort_s
- cmp di,xmaxs
- jge s abort_s
-
- call srotatey ; x is ok, solve for y
-
- if perfect_stars eq yes
- mov eax,ecx
- cdq
- idiv ebp
- mov ecx,eax
- endif
-
- cmp cx,ymins
- jl s abort_s
- cmp cx,ymaxs ; ymaxs1 if larger star (for high res screens)
- jge abort_s
-
- mov edi, current_page ; point to active vga page
- add bx,xcent
- add cx,ycent
-
- movzx esi,cx
- shl si,1
- mov ax,[esi+fastimultable] ; get offset to start of line
-
- mov cx, bx ; copy to extract plane # from
- shr bx, 2 ; x offset (bytes) = xpos/4
- add bx, ax ; offset = width*ypos + xpos/4
-
- mov ax, map_mask_plane1 ; map mask & plane select register
- and cl, plane_bits ; get plane bits
- shl ah, cl ; get plane select value
- out_16 sc_index, ax ; select plane
-
- pop eax ; select colour for star
- push eax
- and al,3 ; four colours
- add al,starcolour
-
- movzx ebx,bx
- mov b [edi+ebx],al ; draw pixel, red or blue is good
- ; add edi,xactual/4
- ; mov [edi+ebx],16 ; draw larger bullet/pixel
-
- ; if drawing larger star, change above code to this!
- ; cmp cx,ymaxs1
- ; jge s abort_s
- abort_s:
- pop esi
- skipit:
- if use_half_stars eq yes
- cmp si,starhalfpoint
- jae outhandle
-
- else
- cmp si,number_of_stars-1-cut
- jae s outhandle
- endif
-
- inc si
- dec angle_count
- jnz more_stars
-
- outhandle:
- if useborders eq yes
- mov ax,xmin
- mov bx,xmax
- mov cx,ymin
- mov dx,ymax
-
- dec bx
- dec dx
-
- mov lxupdate+0,ax
- mov lxupdate+2,bx
- mov lyupdate+0,cx
- mov lyupdate+2,dx
- endif
-
- ret
-
- ; pre-multiply ematrix_row*constant_for_row
- ; to generate new matrix
-
- ; this can be done because we don't have any
- ; camera location offsets (stars are at a
- ; fixed distance from the camera)
-
- align 16
-
- if perfect_stars eq yes
-
- set_star_matrix:
- mov ebx,ematrix+0
- cmul eax,ebx,ratiox
- mov smatrix+0,eax
-
- if usez eq yes ; if not using z rotation, ematrix+4 =0
- mov ebx,ematrix+4
- cmul eax,ebx,ratiox
- mov smatrix+4,eax
- endif
-
- mov ebx,ematrix+8
- cmul eax,ebx,ratiox
- mov smatrix+8,eax
-
- mov ebx,ematrix+12
- cmul eax,ebx,ratioy
- mov smatrix+12,eax
-
- mov ebx,ematrix+16
- cmul eax,ebx,ratioy
- mov smatrix+16,eax
-
- mov ebx,ematrix+20
- cmul eax,ebx,ratioy
- mov smatrix+20,eax
-
- ret
-
- ; if perfect_stars = no, stars will not go through correct 3d calculation
- ; but will be calculated 40% faster. you must set the values xstar and
- ; ystar to 3d quick multipliers so this matrix calculation makes the
- ; stars "look" the same. I did this by moving the camera around and testing
- ; if the stars moved the same as the objects. I did this because the objects
- ; go through the correct 3d calculation and this gave me a base by which to
- ; adjust these numbers.
-
- else
-
- set_star_matrix:
- mov ebx,ematrix+0
- cmul eax,ebx,xstar
- shr eax,2
- mov smatrix+0,eax
-
- if usez eq yes ; if not using z rotation, ematrix+4 =0
- mov ebx,ematrix+4
- cmul eax,ebx,xstar
- shr eax,2
- mov smatrix+4,eax
- endif
-
- mov ebx,ematrix+8
- cmul eax,ebx,xstar
- shr eax,2
- mov smatrix+8,eax
-
- mov ebx,ematrix+12
- cmul eax,ebx,ystar
- shr eax,2
- mov smatrix+12,eax
-
- mov ebx,ematrix+16
- cmul eax,ebx,ystar
- shr eax,2
- mov smatrix+16,eax
-
- mov ebx,ematrix+20
- cmul eax,ebx,ystar
- shr eax,2
- mov smatrix+20,eax
-
- ret
- endif
-
- ; rotate star using smatrix (imported from math.inc)
-
- align 16
-
- srotatex:
- mov eax,smatrix+8
- imul ebp
- shrd eax,edx,14
- mov edi,eax
- if usez eq yes
- mov eax,smatrix+4
- imul ecx
- shrd eax,edx,14
- add edi,eax
- endif
- mov eax,smatrix+0
- imul ebx
- shrd eax,edx,14
- add edi,eax ; di = new x
- ret
-
- align 16
-
- srotatey:
- mov eax,smatrix+16
- imul ecx
- shrd eax,edx,14
- mov ecx,eax
- mov eax,smatrix+20
- imul ebp
- shrd eax,edx,14
- add ecx,eax
- mov eax,smatrix+12
- imul ebx
- shrd eax,edx,14
- add ecx,eax ; cx = new y
-
- mov ebp,esi
- mov ebx,edi
- ret
-
- if perfect_stars eq yes
- align 16
-
- srotatez:
- mov eax,ematrix+32
- imul ebp
- shrd eax,edx,14
- mov esi,eax
- mov eax,ematrix+28
- imul ecx
- shrd eax,edx,14
- add esi,eax
- mov eax,ematrix+24
- imul ebx
- shrd eax,edx,14
- add esi,eax ; si = new z
-
- ret
- endif
-
- code32 ends
- end